package com.kifas.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.kifas.entity.AkunMasterEntity;
import com.kifas.entity.BukuPiutangEntity;
import com.kifas.entity.CustomerEntity;
import com.kifas.entity.PiutangEntity;
import com.kifas.entity.TypeAkunEntity;
import com.kifas.model.xml.AkunMasterModel;
import com.kifas.model.xml.BukuPiutangModel;
import com.kifas.model.xml.CustomerModel;
import com.kifas.model.xml.JenisCustomerModel;
import com.kifas.model.xml.PersistStatus;
import com.kifas.model.xml.PiutangModel;
import com.kifas.model.xml.SalesModel;
import com.kifas.model.xml.TypeAkunModel;
import com.kifas.service.EntityServiceManager;

@Component
@Scope("prototype")
@Path("/Piutangs")
public class PiutangController {

	private static Logger log = Logger.getLogger(PiutangController.class);

	@Context
	UriInfo uriInfo;

	@Autowired
	private EntityServiceManager entityManager;

	@GET
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangs() {
		return transformList(entityManager.getPiutangs());
	}

	@GET
	@Path("{id}")
	@Produces(MediaType.TEXT_XML)
	public PiutangModel getPiutang(@PathParam("id") Long idPiutang) {
		return transform(entityManager.getPiutang(idPiutang));
	}

	@GET
	@Path("JatuhTempo/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempo(@PathParam("days") int days) {
		return transformList(entityManager.getPiutangs(days));
	}

	@GET
	@Path("JatuhTempo/BelumLunas/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempoBlmLns(@PathParam("days") int days) {
		return checkLunas(transformList(entityManager.getPiutangs(days)), false);
	}

	@GET
	@Path("JatuhTempo/Lunas/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempoLns(@PathParam("days") int days) {
		return checkLunas(transformList(entityManager.getPiutangs(days)), true);
	}

	@GET
	@Path("BelumLunas")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangBlmLns() {
		return checkLunas(transformList(entityManager.getPiutangs()), false);
	}
	
	@GET
	@Path("Lunas")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangLns() {
		return checkLunas(transformList(entityManager.getPiutangs()), true);
	}

	@GET
	@Path("BelumLunas/Range")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangBlmLns(@QueryParam("start") String start, @QueryParam("end") String end) {
		SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyy");
		try {
			return checkLunas(transformList(entityManager.getPiutangs(formatter.parse(start), formatter.parse(end))), false);
		} catch (Exception e) {
			return new ArrayList<PiutangModel>();
		}
	}

	@GET
	@Path("Lunas/Range")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangLns(@QueryParam("start") String start, @QueryParam("end") String end) {
		SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyy");
		try {
			return checkLunas(transformList(entityManager.getPiutangs(formatter.parse(start), formatter.parse(end))), true);
		} catch (Exception e) {
			return new ArrayList<PiutangModel>();
		}
	}

	@GET
	@Path("Customer/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempo(@PathParam("id") Long idCustomer) {
		CustomerEntity customer = entityManager.getCustomer(idCustomer);
		return transformList(entityManager.getPiutangs(customer));
	}

	@GET
	@Path("Customer/BelumLunas/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempoBlmLns(@PathParam("id") Long idCustomer) {
		CustomerEntity customer = entityManager.getCustomer(idCustomer);
		return checkLunas(transformList(entityManager.getPiutangs(customer)), false);
	}

	@GET
	@Path("Customer/Lunas/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<PiutangModel> getPiutangJatuhTempoLns(@PathParam("id") Long idCustomer) {
		CustomerEntity customer = entityManager.getCustomer(idCustomer);
		return checkLunas(transformList(entityManager.getPiutangs(customer)), true);
	}

	@PUT
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public PersistStatus update(JAXBElement<PiutangModel> xml) {
		return new PersistStatus("PiutangEntity", "dropped", "update not implement yet");
	}

	@POST
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public PersistStatus insert(JAXBElement<PiutangModel> xml) {
		PiutangModel model = xml.getValue();
		List<BukuPiutangModel> bukuPiutangModels = model.getBukuPiutangModels();
		List<BukuPiutangEntity> bukuPiutangs = null;
		if (bukuPiutangModels != null) {
			bukuPiutangs = new ArrayList<BukuPiutangEntity>();
			for (BukuPiutangModel bukuPiutangModel : bukuPiutangModels) {
				AkunMasterEntity akunMaster = entityManager.getAkunMaster(bukuPiutangModel.getAkunMaster().getKodeAkun());
				bukuPiutangs.add(new BukuPiutangEntity(bukuPiutangModel.getIdBukuPiutang(), akunMaster, bukuPiutangModel.getDebet(), bukuPiutangModel
						.getKredit(), bukuPiutangModel.getTanggal(), bukuPiutangModel.getKeterangan(), bukuPiutangModel.getPosting(), bukuPiutangModel
						.getNoFaktur(), bukuPiutangModel.getDeskripsi(), model.getJumlah(), model.getCreatedBy(), model.getCreatedDate()));
			}
		}
		CustomerEntity customer = entityManager.getCustomer(model.getCustomer().getIdCustomer());
		try {
			PiutangEntity piutang = new PiutangEntity(null, customer, model.getTanggal(), model.getTanggalJatuhTempo(), model.getSyaratBayar(),
					model.getNoFaktur(), model.getJumlah(), model.getKeterangan(), model.getNoReferensi(), new HashSet<BukuPiutangEntity>(bukuPiutangs),
					model.getCreatedBy(), model.getCreatedDate());
			entityManager.persist(piutang);
		} catch (Exception e) {
			log.error("can not persist piutang entity", e);
			return new PersistStatus("PiutangEntity", "failed", "can not persist piutang entity");
		}
		return new PersistStatus("PiutangEntity", "success", "success save Data Piutang...");
	}

	private List<PiutangModel> transformList(List<PiutangEntity> piutangs) {
		List<PiutangModel> piutangModels = new ArrayList<PiutangModel>();
		for (PiutangEntity piutang : piutangs) {
			piutangModels.add(transform(piutang));
		}
		System.out.println("piutangModels : " + piutangModels.size());
		return piutangModels;
	}

	private PiutangModel transform(PiutangEntity piutang) {
		CustomerEntity customer = piutang.getCustomer();
		// JenisCustomerEntity jenisCustomer = customer.getJenisCustomer();
		SalesModel sales = new SalesModel(customer.getSales().getIdSales(), customer.getSales().getNama(), customer.getSales().getType(), customer.getSales()
				.getCreatedBy());
		JenisCustomerModel jenisCustomerModel = new JenisCustomerModel(customer.getJenisCustomer().getIdJenisCustomer(), customer.getJenisCustomer()
				.getJenisCustomer(), customer.getJenisCustomer().getCreatedBy());
		CustomerModel customerModel = new CustomerModel(customer.getIdCustomer(), customer.getNama(), customer.getAlamat1(), customer.getAlamat2(),
				customer.getNoTelp(), customer.getEmail(), customer.getContactPerson(), jenisCustomerModel, customer.getAlamat3(), customer.getNoTelp1(),
				customer.getNoTelp2(), customer.getContactPerson1(), customer.getFax(), customer.getNpwp(), customer.getBank_acc(), customer.getTgl_entry(),
				sales, customer.getCreatedBy());
		List<BukuPiutangEntity> bukuPiutangs = entityManager.getBukuPiutangs(piutang);
		List<BukuPiutangModel> bukuPiutangModels = new ArrayList<BukuPiutangModel>();
		if (bukuPiutangs != null) {
			for (BukuPiutangEntity bukuPiutang : bukuPiutangs) {
				AkunMasterEntity akunMasterEntity = bukuPiutang.getAkunMaster();
				TypeAkunEntity typeAkun = akunMasterEntity.getTypeAkun();
				TypeAkunModel typeAkunModel = new TypeAkunModel(typeAkun.getIdType(), typeAkun.getNama(), typeAkun.getDeskripsi(), typeAkun.getKode(),
						typeAkun.getCreatedBy());
				AkunMasterModel akunMaster = new AkunMasterModel(akunMasterEntity.getKodeAkun(), akunMasterEntity.getNama(), akunMasterEntity.getDk(),
						akunMasterEntity.getIdParentAkun(), akunMasterEntity.isActive(), akunMasterEntity.getDeskripsi(), akunMasterEntity.getNamaPanjang(),
						typeAkunModel, akunMasterEntity.getCreatedBy());
				bukuPiutangModels.add(new BukuPiutangModel(bukuPiutang.getIdBukuPiutang(), akunMaster, bukuPiutang.getDebet(), bukuPiutang.getKredit(),
						bukuPiutang.getTanggal(), bukuPiutang.getKeterangan(), bukuPiutang.getPosting(), bukuPiutang.getNoFaktur(), bukuPiutang.getDeskripsi(),
						bukuPiutang.getSisaBayar(), bukuPiutang.getCreatedBy(), bukuPiutang.getCreatedDate()));
			}
		}
		return new PiutangModel(piutang.getIdPiutang(), customerModel, piutang.getTanggal(), piutang.getTanggalJatuhTempo(), piutang.getSyaratBayar(),
				piutang.getNoFaktur(), piutang.getJumlah(), piutang.getKeterangan(), piutang.getNoReferensi(), bukuPiutangModels, piutang.getCreatedBy(),
				piutang.getCreatedDate());
	}

	private List<PiutangModel> checkLunas(List<PiutangModel> l, boolean isLunas) {
		log.debug("l : " + l.size());
		List<PiutangModel> lResult = new ArrayList<PiutangModel>();
		boolean lunas = false;
		for (PiutangModel p : l) {
			lunas = false;
			for (BukuPiutangModel bp : p.getBukuPiutangModels()) {
				if (bp.getSisaBayar().compareTo(new BigDecimal(0)) == 0) {
					lunas = true;
				}
			}
			if (lunas == isLunas) lResult.add(p);
		}
		return lResult;
	}
}
